#include "function.h"
// 查询链表名是否重复，重复则返回1,不重复则返回0；
int fundRepeat(LIST head, char tempname[])
{
    LIST temp = head;
    if (temp == NULL) // 链表为空直接返回0
    {
        return 0;
    }
    while (temp != NULL) // 链表不为空
    {
        if (strcmp(temp->name, tempname) == 0)
        {
            return 1;
        }
        temp = temp->next;
    }
    return 0;
}
// 添加链表
LIST addNode(LIST head)
{
    char tempname[21];
    char tempcontent[401];
    char temptime[21];
    LIST newNode = (LIST)malloc(sizeof(LN)); // 申请内存空间，创建新链表节点。
    if (newNode == NULL)
    {
        printf("Memory allocation failed!\n");
        return NULL;
    }
    while (1) // 判断作业名与字数是否超出字，是否重复
    {
        system("clear");
        printf("请输入作业名(字数小于15字,作业名不能重复)：\n");
        fgets(tempname, sizeof(tempname), stdin);
        fflush(stdin);                                                // 清除缓冲区
        if (strlen(tempname) < 15 && fundRepeat(head, tempname) == 0) // 满足作业名不重复，字数小于15，则退出循环。
        {
            break;
        }
    }
    deleteN(tempname);//删掉读入的/n
    strcpy(newNode->name, tempname); // 把作业名读入newNode
    while (1)                        // 判断作业内容字数是否超出
    {
        system("clear");
        printf("请输入作业名(字数小于400字)：\n");
        fgets(tempcontent, sizeof(tempcontent), stdin);
        fflush(stdin);                 // 清除缓冲区
        if (strlen(tempcontent) < 400) // 满足作业内容字数小于400，则退出循环。
        {
            break;
        }
    }
    strcpy(newNode->content, tempcontent); // 把作业内容读入newNode
    while (1)                              // 判断作业时间字数是否超出
    {
        system("clear");
        printf("请输入作业时间(字数小于15字)：\n");
        fgets(temptime, sizeof(temptime), stdin);
        fflush(stdin);             // 清除缓冲区
        if (strlen(temptime) < 15) // 满足作业内容字数小于15，则退出循环。
        {
            break;
        }
    }
    strcpy(newNode->time, temptime); // 把作业时间读入newNode
    newNode->next = NULL;            // 新节点插入链表尾部，所以其next指针初始化为NULL
    if (head == NULL)
    { // 如果链表为空，则将新节点设置为头节点
        head = newNode;
    }
    else
    { // 如果链表不为空，则找到最后一个节点并插入新节点
        LIST temp = head;
        while (temp->next != NULL)
        {
            temp = temp->next;
        }
        temp->next = newNode; // 将最后一个节点的next指针指向新节点
    }
    return head; // 返回头节点的指针
}
// 显示链表所有节点函数
void showNodes(LIST *head)
{
    if (head == NULL)
    { // 如果链表为空，则不显示任何内容
        printf("The linked list is empty.\n");
        return;
    }
    LIST temp = *head; // 从链表头开始遍历
    while (temp != NULL)
    {
        printf("作业名: %s\n", temp->name);
        printf("作业内容: %s\n", temp->content);
        printf("作业截止时间: %s\n", temp->time);
        printf("\n");
        temp = temp->next; // 移动到下一个节点
    }
}
// 删除包含指定专业的节点
void deleteByname(LIST *head)
{
    char deletename[21];
    printf("delete name:");
    scanf("%s", deletename);
    fflush(stdin);
    LIST temp = *head;
    LIST p = NULL;
    while (temp != NULL)
    {
        if ((strcmp(temp->name, deletename)) == 0) // 找到包含指定专业的节点
        {
            if (p == NULL)
            { // 头节点需要单独处理
                *head = temp->next;
                free(temp);
                return;
            }
            else
            { // 非头节点，直接删除并释放内存
                p->next = temp->next;
                free(temp);
            }
        }
        p = temp;          // 移动到下一个节点之前，记录当前节点的前一个节点指针
        temp = temp->next; // 移动到下一个节点，继续查找匹配的节点（如果有）或结束链表遍历（如果没有）
    }
}
// 修改元素内容
LIST alterNode(LIST L)
{
    char tempname[21];
    while (1)
    {
        printf("修改作业名：\n");
        scanf("%s", tempname);
        fflush(stdin); // 清除缓冲区
        LIST P = search(L, tempname);
        if (P == NULL)
        {
            printf("没有您想修改的作业名请重新输入\n");
        }
        else
        {
            printf("如下是您的作业名和内容：\n");
            printf("%s\n", P->name);
            printf("%s\n", P->content);
            strcpy(P->content, ""); // 删除节点的内容
            printf("请重新输入 %s 作业内容:\n", P->name);
            fgets(P->content, sizeof(P->content), stdin); // 修改节点内容，使用fgets可以处理包含空格的输入
            return L;
        }
    }
}
// 释放节点
void listfree(LIST *L)
{
    LIST process = *L, temp = NULL;
    while (process != NULL)
    {                         // 检查 process 不为 NULL，避免空指针解引用
        temp = process->next; // 保存下一个节点的地址
        free(process);        // 释放当前节点
        process = temp;       // 将 process 设置为下一个节点的地址
    }
    *L = NULL; // 将链表头设置为 NULL，避免野指针
}
// 查找节点
LIST search(LIST L, const char *n)
{
    LIST temp = L;
    while (temp != NULL)
    {
        if (strcmp(temp->name, n) == 0) // 使用strcmp比较字符串
        {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}
// 删除fgets读入的/n
void deleteN(char *buffer)
{
    size_t len = strlen(buffer);
    if (len > 0 && buffer[len - 1] == '\n')
    {
        buffer[len - 1] = '\0'; // 将换行符替换为字符串结束符
    }

    // 如果还有回车符（Windows系统的行结束符），也删除它
    if (len > 1 && buffer[len - 2] == '\r')
    {
        buffer[len - 2] = '\0'; // 将回车符替换为字符串结束符
    }
}